package com.junqson.je.user.service;

import com.junqson.je.common.UserHolder;
import com.junqson.je.common.constant.AppRedisKey;
import com.junqson.je.common.exception.BizException;
import com.junqson.je.common.model.User;
import com.junqson.je.common.model.dto.AuthResultDTO;
import com.junqson.je.common.model.dto.MailDTO;
import com.junqson.je.common.model.vo.SimpleUserInfo;
import com.junqson.je.common.util.AppUtil;
import com.junqson.je.user.client.MsgClient;
import com.junqson.je.user.model.Constants;
import com.junqson.je.user.model.RedisConstants;
import com.junqson.je.user.model.UserModel;
import com.junqson.je.user.model.dto.UserDTO;
import com.junqson.je.user.model.enums.Gender;
import com.junqson.je.user.repo.UserRepo;
import com.junqson.je.user.utils.MailTemplateUtil;
import freemarker.template.TemplateException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Descriptions
 * @Company
 * @Author Junqson
 * @Date 2020/1/22 22:18
 * @Version 1.0
 */
@Service
public class UserService {

    @Autowired
    private UserRepo userRepo;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private MsgClient msgClient;

    @Autowired
    private MailTemplateUtil mailTemplateUtil;


    public UserModel findByPhone(String phone) {
        return userRepo.findByPhone(phone);
    }


    public UserModel createUser(String phone) {
        UserModel user = new UserModel();
        Date time = new Date();
        user.setCreateTime(time);
        user.setHeadIcon(Constants.DEFAULT_HEAD_ICON);
        user.setUsername(Constants.getDefaultUserName(phone));
        user.setPhone(phone);
        user.setLastLogin(time);
        userRepo.save(user);
        return user;
    }

    public void updateLastLogin(UserModel user) {
        user.setLastLogin(new Date());
        userRepo.save(user);
    }

    public UserModel getUserById(Integer userId) {
        return userRepo.findByUserId(userId);
    }

    public User loadUserCache(Integer userId) {
        UserModel userModel = userRepo.findByUserId(userId);
        if (userModel == null) {
            throw new BizException(1, "用户不存在");
        }
        User user = new User();
        AppUtil.copyPropertiesIgnoreNull(userModel, user);

        String userK = AppUtil.getRedisKey(AppRedisKey.USER_CACHE, userId.toString());
        redisTemplate.opsForValue().set(userK, user);
        return user;
    }

    public void updateUserInfo(UserDTO user) {
        int uid = UserHolder.get().getUserId();
        int modUid = user.getUserId();

        if (uid != modUid) {
            throw new BizException(1, "用户id非法");
        }

        UserModel userModel = userRepo.findByUserId(uid);
        if (userModel != null) {
            // 处理性别
            try {
                Gender g = Gender.valueOf(user.getGender());
            } catch (Exception e) {
                throw new BizException(1, "性别非法");
            }
            AppUtil.copyPropertiesIgnoreNull(user, userModel);

            userRepo.save(userModel);
        }

        // 清除缓存
        String userK = AppUtil.getRedisKey(AppRedisKey.USER_CACHE, String.valueOf(uid));
        redisTemplate.delete(userK);
        String suinfoK = AppUtil.getRedisKey(RedisConstants.SIMPLE_USER_INFO, String.valueOf(uid));
        redisTemplate.delete(suinfoK);
    }



    public void passUserAuth(AuthResultDTO authResultDTO) throws IOException, TemplateException {
        UserModel userModel = userRepo.findByUserId(authResultDTO.getUserId());
        userModel.setCompany(authResultDTO.getCompany());
        userModel.setTitle(authResultDTO.getTitle());
        userModel.setAuthenticated(true);
        userRepo.save(userModel);


        // 清除缓存
        String userK = AppUtil.getRedisKey(AppRedisKey.USER_CACHE, authResultDTO.getUserId().toString());
        redisTemplate.delete(userK);
        String suinfoK = AppUtil.getRedisKey(RedisConstants.SIMPLE_USER_INFO, authResultDTO.getUserId().toString());
        redisTemplate.delete(suinfoK);

        // 发送认证成功邮件
        String email = userModel.getEmail();
        if (StringUtils.isNotEmpty(email)) {
            Map<String, Object> param = new HashMap<>();
            param.put("username", userModel.getUsername());
            param.put("company", authResultDTO.getCompany());
            param.put("title", authResultDTO.getTitle());
            MailDTO mailDTO = mailTemplateUtil.getMailDTO(MailTemplateUtil.AUTH_SUCCESS, email, param);
            msgClient.sendMail(mailDTO);
        }


    }

    public void userAuthFailed(AuthResultDTO authResultDTO) throws IOException, TemplateException {
        // 发送认证失败邮件
        UserModel userModel = userRepo.findByUserId(authResultDTO.getUserId());
        String email = userModel.getEmail();
        if (StringUtils.isNotEmpty(email)) {
//            MailDTO mailDTO = MailTemplate.getMailDTO(MailTemplate.AUTH_FAILED, email, authResultDTO.getResultMsg());
            Map<String, Object> param = new HashMap<>();
            param.put("username", userModel.getUsername());
            param.put("reason", authResultDTO.getResultMsg());
            MailDTO mailDTO = mailTemplateUtil.getMailDTO(MailTemplateUtil.AUTH_FAILED, email, param);
            msgClient.sendMail(mailDTO);
        }
    }


    /**
     * 获取简单用户信息
     * @param userId
     * @return
     */
    public SimpleUserInfo getSimpleUserInfo(Integer userId) {
        String suinfoK = AppUtil.getRedisKey(RedisConstants.SIMPLE_USER_INFO, userId.toString());
        Object suObj = redisTemplate.opsForValue().get(suinfoK);
        if (suObj != null) {
            // 更新过期时间
            redisTemplate.expire(suinfoK, RedisConstants.SIMPLE_USER_INFO_EXPIRE, TimeUnit.HOURS);
            return (SimpleUserInfo) suObj;
        }

        UserModel userModel = userRepo.findByUserId(userId);
        if (userModel != null) {
            SimpleUserInfo simpleUserInfo = new SimpleUserInfo();
            AppUtil.copyPropertiesIgnoreNull(userModel, simpleUserInfo);
            redisTemplate.opsForValue().set(suinfoK, simpleUserInfo, RedisConstants.SIMPLE_USER_INFO_EXPIRE, TimeUnit.HOURS);
            return simpleUserInfo;
        }
        return null;


    }

}


